PRE: Se tiene un conjunto LP de puntos (x,y) que corresponden a direcciones de entrega de paquetes

LP <- Conjunto de direcciones para los que se generara la ruta
H <- Cantidad de hormigas
S <- Solucion local (orden en el recorrido)
SF <- Mejor solucion final

Funcion Main()
{
	Zonas = {}
	//dividir LP en pedidos de maximo 25 paquetes (funcion)
	S = generaRuta(CantidadCasas, LP, false) //Obtiene una sola ruta /*solo aplicar grasp*/

	
	Zonas = particionarEnZonas(S) //Cada zona contiene una ruta que cumple con las restricciones de capacidad de los vehiculos
	
	for i=1 to Zonas.CantidadZonas //Para cada zonas verifico si se cumplen todos los plazos de entrega
	{
		cumplio = CumplenPlazos(Zonas(i))
		if (!cumplio)
		{
			considerarPlazos = true
			rutaOptimizada = generaRuta(Zonas(i).CantidadCasas, Zonas(i), considerarPlazos) //empezara oliendo casas porque ya antes se ha llenado los caminos de feromonas y ahora considerara plazos
			/*solo colonia d hormigas*/
			/*gebnerar varias rutas optimizadas*/
			cumplio = CumplenPlazos(rutaOptimizada)
			if (rutaOptimizada.costoRuta <= Zonas(i).costoRuta)
			{
				Zonas(i) = rutaOptimizada
			}
		}
		//en cada zona, indicar el id de vehiculo que le ha sido asignado
	}
	Devolver Zonas //Zonas es el conjunto de rutas cada una con el debido vehiculo asignado
}

Funcion generaRuta(H, LP, considerarPlazos) /*solo colinia d hormigas, sin usar grasp, q estaria en otro a funcion*/
{
	vez = 1
	S = {}
	SF = {}
	Mientras (!condicionParada(considerarPlazos)){
		Para i=1 hasta H  //Deberia ser con hilos creo...?
		{
			Si (vez ==1) entonces
				S = generarOrdenAleatorioEnRecorrido(LP) //Obtiene una lista S con el orden del recorrido casi casi aleatoria
			sino
			{
				S = generarOrdenEnRecorrido(LP, considerarPlazos) 
			}
			ActualizarMejorSolucion(S, SF, considerarPlazos) //Se compara la solucion generada con la mejor solucion hasta ahora segun una funcion de costos sin considerar plazos
			ActualizarTodasFeromonas(S, TablaFeromonas[][]) //Supongo que la cantidad de feromonas que se suman depende de que tan eficiente resulto la ruta generada?
		}
		EvaporarFeromonas(TablaFeromonas[][]) //Se evaporan en solo una ligera intensidad
		vez++	
	}
	Devolver S
}

Funcion generarOrdenAleatorioEnRecorrido(LP) //GRASP
{
S={}
i=0
criterioAleatorioOgoloso = 0 //0 para un algoritmo goloso, 1 para uno aleatorio
CasasPorRecorrer = LP	
	Mientras (!vacio(CasasPorRecorrer) //No se ha completado la visita de todas las casa de la lista LP
	{
		mejor = MaximoFuncionCosto(i, CasasPorRecorrer) //Funcion que obtiene el costo en soles de la siguiente casa mas cercana (considerando solo kilometraje por el momento)
		peor = MinimoFuncionCosto(i, CasasPorRecorrer) //Funcion que obtiene el costo en soles de la casa mas lejana
		CasasSiguientesAceptables = rangoAceptacion(mejor, peor, LP, CasasPorRecorrer, criterioAleatorioOgoloso) //Primero halla los limites para los costos en funcion a la casa mas lejana y mas cercana, dentro del rango definido por estos limites se considerara como 'aceptable' la visita a una casa siguiente.. estas opciones de casas aceptables se guardan en la lista de resultados
		opcionCasaSiguiente = Random(CasasSiguientesAceptables)
		Si (cumplePlazo(OpcionCasaSiguiente) && algunaOtraRestriccion(opcionCasaSiguiente) //Not sure if debe ir la corroboracion del plazo aqui..
		{
			S.agregarCasaARecorrido(OpcionCasaSiguiente)
			i++
			CasasPorRecorrer = CasasPorRecorrer - {i}
		}
	}
Ruta = S
Devolver Ruta
}

Funcion generarOrdenEnRecorrido(LP)
{
	S = {} //S es la lista con los puntos en el orden en el que son recorridos
	Mientras (!todasCasasVisitadas)
	{
		next = olerSiguienteCasa(UbicacionActualXY, TablaFeromonas[][], TablaDistanciaEntreCasa[][], ListaCasasYaVisitadas(hormigaActual), considerarPlazos) //Se usa la tabla de feromonas. Las feromonas se marcan entre casas, es decir entre una casa i y una casa j. Tambien en la funcion se usa el factor "distancia" entre una casa i y la j. Combinando ambos criterios es que se hace el calculo. La funcion olerSiguienteCasa es una funcion probabilistica. Dentro de esta funcion se emplea la lista tabu de casas ya visitadas por la hormiga para descartarla como siguiente posibilidad de visita. 
		S = S + {next}
	}
	Devolver S
}

Funcion particionarEnZonas(S)
{
	Zonas = {}
	
	if UnSoloVehiculoNoAbastece(S)
	{
		//Si uno de los puntos necesita toda la capacidad del vehciulo
		
		cx, cy = calcularCentro(S)
		costoHorizontal, SH1, SH2 = PartirHorizontal(S, cx, cy) //Suma de los costos de la ruta de abajo y de arriba incluyendo ida y retorno al almacen
		costoVertical, SV1, SV2 = PartirVertical(S, cx, cy)
		if (costoHorizontal>=costoVerical)
		{
			S1 = SH1
			S2 = SH2
		}
		else
		{
			S1 = SV1
			S2 = SV2
		}
		Zonas1 = particionarEnZonas(S1)
		Zonas2 = particionarEnZonas(S2)
		Zonas.add(Zonas1)		
		Zonas.add(Zonas2)
	}
	else
	{
		if (hayVehiculoParaAsignar)
		{
			Zonas.asignarVehiculo(S)
			Zonas.add(S)
		}		
	}
	Devolver Zonas
}

